#include "common.h"
VOID   Keyboard_Interrupt()//We should not use the message machenism.
{
 //  Print("\nkeyboard interrupt\n");
   MESSAGE message;
   message.destination=KEYBOARDDRIVER;
   message.type=KEYBOARDDRIVER_INTERRUPT;
   message.value0=0xFF&((U4B)KeyboardRead());
   SendMessage(&message);
}
VOID   ATA_Interrupt()
{
  // Print("\nata interrupt\n");
   SIGNAL atasignal;
   atasignal.dt=FSDRIVER;
   atasignal.signal=SIGNAL_ATA;
   NotifyWaited(&atasignal);
}

PUBLIC S4B InitUserPCB
	(PPROCESS p, U4B pid,   PVOID entry,U4B stack, 
	PVOID messagestack,PVOID signalstack,   U4B priority,
	 PCHAR name, PPDE ppde,  PPROCESS prev,PPROCESS next)
{
      if(p==(PPROCESS)PTR_INVALID || pid<1000 || entry<=(PVOID)ADDRESS_VIRTUAL_KERNEL_END)
	  	return ARTIST_ERROR_INVALIDPARAMETER;
	  MESSAGE shack;
	  MemorySet(&shack,sizeof(MESSAGE),0);
	  shack.type=TYPE_INVALID;
	  
	  MemorySet((PVOID)p,sizeof(PROCESS),0);
	  
	  p->p_arcregister.gs=UsrCGA;
	  p->p_arcregister.fs=UsrData;
	  p->p_arcregister.ds=UsrData;
	  p->p_arcregister.es=UsrData;
	  p->p_arcregister.cr3=(((U4B)ppde)&((U4B)0xFFFFF000));
	  p->p_arcregister.cr0=0xE0000011; /*the user process  uses the MMU*/
	  p->p_arcregister.tss_esp0=(sizeof(STACKFRAME)+(U4B)p);
	  p->p_arcregister.tss_ss0=KernelData;
	  p->p_arcregister.eip=(U4B)entry;
       //   Print(" %X ",entry);
	  p->p_arcregister.cs=UsrCode;
	  p->p_arcregister.eflags=0x0202;//IOPL=0,So when the in,ins,out,outs,cli,sti which require CPL<=IOPL are not allowed.
	  p->p_arcregister.esp=0xFFFFFFF0;
	  p->p_arcregister.ss=UsrData;
	  
	  p->p_pid=pid;
	  StringCopy(p->p_name,name,PROCESS_MAXNAME);
	  p->p_priority=priority;
	  p->p_remain=priority;
	  p->p_state=STATE_BORN;
	  p->p_ppde=ppde;
	  p->p_pmessage=(PMESSAGE)messagestack;
	  p->p_messageplace=1;
	  p->p_messageget=0;
	  p->p_messagelimit=PROCESS_USERMESSAGEPAGENUMBER*SIZE_PAGE/sizeof(MESSAGE);
	  p->p_messagequeue=(PPROCESS)PTR_INVALID;
	  p->p_messageshack=shack;
	  p->p_signalplace=1;
	  p->p_signalget=0;
	  p->p_signallimit=PROCESS_USERSIGNALPAGENUMBER*SIZE_PAGE/sizeof(SIGNAL);
	  p->p_psignal=(PSIGNAL)signalstack;
	  p->p_idcard=100;/*0:kernel 100:usr*/
	  p->p_pprocessprev=prev;
	  p->p_pprocessnext=next;
	  return ARTIST_ERROR_OK;   

}
PUBLIC S4B InitKernelPCB(U4B pid,PVOID function,U4B stack,U4B priority,PCHAR name,PPROCESS prev,PPROCESS next)
{
   if((pid>=NUMBER_MAX_KERNEL_PROCESS)||(function==(PVOID)NULL)||(stack<=0x100000)||(stack> 0x200000)||(name==(PCHAR)NULL)||(priority<0))
           return ARTIST_ERROR_INVALIDPARAMETER;
   MESSAGE shack;
   MemorySet(&shack,sizeof(MESSAGE),0);
   shack.type=TYPE_INVALID;
   MemorySet((PVOID)&kernelprocess[pid],sizeof(PROCESS),0);
   PPROCESS p=(PPROCESS)&kernelprocess[pid];
   p->p_arcregister.gs=UsrCGA;
   p->p_arcregister.fs=UsrData;
   p->p_arcregister.ds=UsrData;
   p->p_arcregister.es=UsrData;
   p->p_arcregister.cr3=PTR_INVALID;
   p->p_arcregister.cr0=0x60000011; /*the kernel process don't use the MMU*/
   p->p_arcregister.tss_esp0=sizeof(STACKFRAME)+(U4B)p;
   p->p_arcregister.tss_ss0=KernelData;
   p->p_pmessage=(PMESSAGE)&kernelprocessmessage[pid*PROCESS_MESSAGEPAGENUMBER];
 //  p->p_arcregister.ignore_esp=0x200000;
   p->p_arcregister.eip=(U4B)function;
   p->p_arcregister.cs=UsrCode;
   p->p_arcregister.eflags=0x3202;
   p->p_arcregister.esp=stack;
   p->p_arcregister.ss=UsrData;

   p->p_messageplace=1;
   p->p_messageget=0;
   p->p_messagelimit=PROCESS_MESSAGEPAGENUMBER*SIZE_PAGE/sizeof(MESSAGE);
   p->p_messagequeue=(PPROCESS)PTR_INVALID;
   p->p_messageshack=shack;

   p->p_signalplace=1;
   p->p_signalget=0;
   p->p_signallimit=PROCESS_SIGNALPAGENUMBER*SIZE_PAGE/sizeof(SIGNAL);
   p->p_psignal=(PSIGNAL)&kernelprocesssignal[pid*PROCESS_SIGNALPAGENUMBER];

   p->p_idcard=0;/*0:kernel 100:usr*/
   p->p_pid=pid;
   p->p_priority=priority;
   p->p_remain=priority;
   StringCopy(p->p_name,name,PROCESS_MAXNAME);
   p->p_pprocessprev=prev;
   p->p_pprocessnext=next;
   p->p_state=STATE_BORN;
   p->p_ppde=(PPDE)PTR_INVALID;
   return ARTIST_ERROR_OK;   
}

S4B Init_Manager()
{
   Print("\nhd drive number %X\n",*((PU1B)0x475));

   InitKernelPCB(SERVERMANAGER,(PVOID)GetPhysicalAddress(ServerManager),0x200000-0x4000*SERVERMANAGER ,10,"ServerManager",NULL,NULL);
   ActivateProcess(&kernelprocess[SERVERMANAGER]);
   MESSAGE message;
   message.type=SERVERMANAGER_WHOIAM;
   message.destination=SERVERMANAGER;
   SendMessage(&message);
   
   InitKernelPCB(DRIVERMANAGER,(PVOID)GetPhysicalAddress(DriverManager),0x200000-0x4000*DRIVERMANAGER,10,"DriverManager",NULL,NULL);
   ActivateProcess(&kernelprocess[DRIVERMANAGER]);
   message.type=DRIVERMANAGER_WHOIAM;
   message.destination=DRIVERMANAGER;
   SendMessage(&message);

   InitKernelPCB(AFFAIRMANAGER,(PVOID)GetPhysicalAddress(AffairManager),0x200000-0x4000*AFFAIRMANAGER,10,"AffairManager",NULL,NULL);
   ActivateProcess(&kernelprocess[AFFAIRMANAGER]);
   message.type=AFFAIRMANAGER_WHOIAM;
   message.destination=AFFAIRMANAGER;
   SendMessage(&message);

   InitKernelPCB(INTERFACEMANAGER,(PVOID)GetPhysicalAddress(InterfaceManager),0x200000-0x4000*INTERFACEMANAGER,10,"InterfaceManager",NULL,NULL);
   ActivateProcess(&kernelprocess[INTERFACEMANAGER]);
   message.type=INTERFACEMANAGER_WHOIAM;
   message.destination=INTERFACEMANAGER;
   SendMessage(&message);
  // Assert(0);
   return ARTIST_ERROR_OK;
}
VOID SystemCallInterrupt(U4B type,U4B p1,U4B p2,U4B p3)
{
   __asm__ __volatile__(
        "int  $0xFF\n\t"
         :
         :"a"(type),"b"(p1),"c"(p2),"d"(p3)
         
          );
}

VOID  IntelInterruptHandler(U1B vector,U4B errorcode,U4B eip,U2B cs,U4B eflags)
{
   if(vector>31)
     return;
   PCHAR message[]={
                      "0:#DE",       "1:#DB", "2:NMI", "3:#BP", "4:#OF",
                      "5:#BR",       "6:#UD", "7:#NM", "8:#DF", "9:CSO",
                      "10:#TS",      "11:#NP","12:#SS","13:#GP","14:#PF",
                      "15:#Reserved","16:#MF","17:#AC","18:#MC","19:#XF"
                   };
   if(vector>19)
   {
     Print("The vector number:0x%#0cX is reserved now.\n",vector);
     return;
   }
   Print("The vector number is 0x%#0cX,the message:%#0cs,the errorcode is 0x%#0cX,the eip is 0x%#0cX,the cs is 0x%#0cX,the eflags is 0x%#0cX\n",
         vector,message[vector],errorcode,eip,cs,eflags);
}

INLINE S4B Init_Env()
{
   /*-----------Get the parameters from the loader---------------*/
    S2B  j=0,k=0;
    S2B  i     = (S2B)MemoryGet4Byte(ADDRESS_PARAMETER_NUMBER_LOADER_TO_KERNEL);
    for(j=0;j<i;j++){
      PKERNELPARAMETER p_parameters=(PKERNELPARAMETER)(ADDRESS_PARAMETER_FIRST_PARAMETER+sizeof(KERNELPARAMETER)*j);
 //     Print("%#0cX,%#0cX,%#0cX,%#0cX,%#0cX,%#0cX,%#0cX,%#0cX\n",p_parameters->p1,p_parameters->p2,p_parameters->p3,p_parameters->p4,p_parameters->p5,p_parameters->p6,p_parameters->p7,p_parameters->p8);
 //Assert(0);   
   switch(p_parameters->p1)
   {
        case TYPE_PARAMETER_RAMSIZE_LOADER_TO_KERNEL:
        { 
			ramsize=p_parameters->p2;
			break;
		}
        case TYPE_PARAMETER_MEMORYMAP_LOADER_TO_KERNEL:
        { 
			if(p_parameters->p4==TYPE_PARAMETER_RAM_AVAILABLE)
            {
                   ramavailable[k].start=p_parameters->p2;
				   ramavailable[k].size=p_parameters->p3;
				   k++;
				   break;
			}
        }
        case TYPE_PARAMETER_KERNELSIZE_LOADER_TO_KERNEL:
        {
			kernelmap.start=p_parameters->p2;
			kernelmap.size=p_parameters->p3;
			break;
	    }
     }      
   }
   /*-----------Init the memory page block ----------------------*/
   S2B m=0;
   U4B rambuffer[NUMBER_MAX_MEMORY_SECTION*2]; /*this  means the memory is allowed to be divided into NUMBER_MAX_MEMORY_SECTION sections*/
   U4B ramnumber=0;
   for(;m<k;m++)  /*These code is just to make sure where can be used .*/
   {
       if(ramavailable[m].size<SIZE_PAGE) /*If the memory section is less than a page size,we don't use it.*/
         continue;
       
       U4B start,end;
       start = ramavailable[m].start;
       end   = ramavailable[m].size+start;
       if(start<ADDRESS_KERNEL_START)/*In the memory ,in the lower place ,there may be some empty page.*/
       {
           if(end<=ADDRESS_KERNEL_START)
           {
               rambuffer[ramnumber*2]=start;
               rambuffer[ramnumber*2+1]=end;
               ramnumber++;
               continue;
           }
           if(end>ADDRESS_KERNEL_START && end<=ADDRESS_KERNEL_END)  /*the end pointer is in the kernel*/
           {
               end=ADDRESS_KERNEL_START;
               rambuffer[ramnumber*2]=start;
               rambuffer[ramnumber*2+1]=end;
               ramnumber++;
               continue;
           }
           rambuffer[ramnumber*2]=start;
           rambuffer[ramnumber*2+1]=ADDRESS_KERNEL_START;
           ramnumber++;
           rambuffer[ramnumber*2]=ADDRESS_KERNEL_END;
           rambuffer[ramnumber*2+1]=end;
           ramnumber++;
           continue;
       }
       if(start>=ADDRESS_KERNEL_START && start<ADDRESS_KERNEL_END) /*the kernel use 0~(10M-1)*/
       {
           if(end<=ADDRESS_KERNEL_END) continue;
           rambuffer[ramnumber*2]=ADDRESS_KERNEL_END;
           rambuffer[ramnumber*2+1]=end;
           ramnumber++;
           continue;
       }
       rambuffer[ramnumber*2]=start;
       rambuffer[ramnumber*2+1]=end;
       ramnumber++;
       continue; 
   }
//   for(m=0;m<ramnumber;m++)
//    Print("%X,%X;",rambuffer[m*2],rambuffer[m*2+1]);
//   Assert(ramnumber>0);
//   Assert(0);
   PPAGEBLOCK block=(PPAGEBLOCK)ADDRESS_KERNEL_PAGE_BLOCK_FLAG;
   U4B  pagenumber=0;
   block->time=0;
   block->attribute=PAGETAG|PAGEFIXED;
   block->page=(PPAGE)PTR_INVALID;
   block->owner=(PPROCESS)PTR_INVALID;
   block->prevblock=(PPAGEBLOCK)PTR_INVALID;
   block->nextblock=(PPAGEBLOCK)PTR_INVALID;
   block++;
   for(i=0;i<ramnumber;i++)
   {
      U4B start,end;
      start=rambuffer[i*2];end=rambuffer[i*2+1];
	  if(end<=start) continue;
      if((end-start)<SIZE_PAGE) continue;
      start=((start+SIZE_PAGE-1)/SIZE_PAGE)*SIZE_PAGE;  /*delete the head*/
      end  =(end/SIZE_PAGE)*SIZE_PAGE;                  /*delete the tail*/
      if((end-start)<SIZE_PAGE) continue;

      for(;start<end;start+=SIZE_PAGE)
      {
         block->time=(U4B)0;
         block->attribute=PAGEFREE;
         block->page=(PPAGE)start;
         block->owner=(PPROCESS)PTR_INVALID;
         block->prevblock=(PPAGEBLOCK)(block-1);
         block->nextblock=(PPAGEBLOCK)PTR_INVALID;
         block--;
         block->nextblock=(PPAGEBLOCK)(block+1);
         block+=2;        
         pagenumber++;
      }
   }
   /*Here the block point to the a empty block.*/
   block--;
   block->nextblock=(PPAGEBLOCK)ADDRESS_KERNEL_PAGE_BLOCK_FLAG;
   ((PPAGEBLOCK)ADDRESS_KERNEL_PAGE_BLOCK_FLAG)->prevblock=block;
   ((PPAGEBLOCK)ADDRESS_KERNEL_PAGE_BLOCK_FLAG)->time=pagenumber;
   /*Here the block construct a circle contain the first block which is just a flag not to present a page.and its member time presents the number of
     of the page(the block)*/
   pblock=(PPAGEBLOCK)ADDRESS_KERNEL_PAGE_BLOCK_FLAG;
//   Print("%X",block);Assert(0);

   /*---------------------------------------PDE,PTE----------------------------------------------------------------*/
   /*All the process is under the Ring 3.
     Processes except the kernel processes  use the MMU,so I prepare a pde and a pte for the process using MMU .
     For the process ,virtual address 0-1G is for the kernel.
     The common process can only use the virtual address 1G-4G  */
  // MemorySet(&pde,sizeof(pde),0);
  // for(i=0;i<256;i++) 
  //   pde.room[i]=3;
  // for(i=256;i<1024;i++) 
  //   pde.room[i]=6;
  // MemorySet(&pte,sizeof(pte),0);
   //for(i=0;i<1024;i++) 
   //  pte.room[i]=i*(0x1000)+3;
   
  /*-----------------------------------------fsbuffer---------------------------------------------------------*/
   fsbuffer=(PU1B)ADDRESS_KERNEL_FILE_BUFFER;
      
  /*-----------------------------------------message and signal buffer----------------------------------------*/
   kernelprocessmessage=(PPAGE)ADDRESS_KERNEL_MESSAGE_BUFFER;
   kernelprocesssignal=(PPAGE)ADDRESS_KERNEL_SIGNAL_BUFFER;
   pidnext=1000;
   return ARTIST_ERROR_OK;
}

INLINE S4B Init_Machine()
{
       /*-----------Init the tss struct------------------------------*/
   MemorySet(&tss,sizeof(TSS),0x00);
   tss.ss0=(U2B)Kernel_SS;
   tss.iobitmapbase=(U2B)sizeof(TSS);
   tss.esp0=(U4B)GetPhysicalAddress(kernelprocess[0])+sizeof(STACKFRAME);
   /*-----------Init the gdt struct and the gdtptr struct--------*/
   MemorySet(gdt,sizeof(GDTDESCRIPTOR)*GDT_AMOUNT,0x00);
   MakeGDTDescriptor(gdt[GDTKernelCode],0,0xFFFFFFFF,0x9A);
   MakeGDTDescriptor(gdt[GDTKernelData],0,0xFFFFFFFF,0x92);
   MakeGDTDescriptor(gdt[GDTKernelCGA],0xB8000,0x8000,0x92);
   MakeGDTDescriptor(gdt[GDTTSS],(U4B)GetPhysicalAddress(tss),(sizeof(TSS)-1),0x89);
   MakeGDTDescriptor(gdt[GDTUsrCode],0,0xFFFFFFFF,0xFA);
   MakeGDTDescriptor(gdt[GDTUsrData],0,0xFFFFFFFF,0xF2);
   MakeGDTDescriptor(gdt[GDTUsrCGA],0xB8000,0x8000,0xF2);
   MakeGDTPtr(gdtptr,(GDTSize-1),(GetPhysicalAddress(gdt)));
   /*----------Init the idt table--------------------------------*/
   MemorySet(idt,sizeof(GATE)*IDT_AMOUNT,0x00);
   S4B i;
   for(i=0;i<IDT_AMOUNT;i++)
   MakeGateDescriptor(idt[i],(GetPhysicalAddress(UselessInterruptHandler)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[0],(GetPhysicalAddress(DivideError_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[1],(GetPhysicalAddress(Debug_FaultTrap)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[2],(GetPhysicalAddress(NMI_Interrupt)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[3],(GetPhysicalAddress(Breakpoint_Trap)),GDTSelectorIDT,0xEE);
   MakeGateDescriptor(idt[4],(GetPhysicalAddress(Overflow_Trap)),GDTSelectorIDT,0xEE);
   MakeGateDescriptor(idt[5],(GetPhysicalAddress(BoundsCheck_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[6],(GetPhysicalAddress(InvalidOpcode_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[7],(GetPhysicalAddress(DeviceNotAvailable_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[8],(GetPhysicalAddress(DoubleFault_Abort)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[9],(GetPhysicalAddress(CoprocessorSegmentOverrun_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[10],(GetPhysicalAddress(InvalidTSS_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[11],(GetPhysicalAddress(SegmentNotPresent_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[12],(GetPhysicalAddress(StackSegment_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[13],(GetPhysicalAddress(GeneralProtection_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[14],(GetPhysicalAddress(PageFault_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[15],(GetPhysicalAddress(ReservedInterrupt_NotUsed)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[16],(GetPhysicalAddress(CoprocessorError_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[17],(GetPhysicalAddress(AlignmentCheck_Fault)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[18],(GetPhysicalAddress(MachineCheck_Abort)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[19],(GetPhysicalAddress(SIMDFloatingPointException_Fault)),GDTSelectorIDT,0x8E);
   
   MakeGateDescriptor(idt[IDT_Master8259A_Timer],(GetPhysicalAddress(Master8259A_Timer)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_Keyboard],(GetPhysicalAddress(Master8259A_Keyboard)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_SerialPort2],(GetPhysicalAddress(Master8259A_SerialPort2)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_SerialPort1],(GetPhysicalAddress(Master8259A_SerialPort1)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_LPT2],(GetPhysicalAddress(Master8259A_LPT2)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_Floppy],(GetPhysicalAddress(Master8259A_Floppy)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Master8259A_LPT1],(GetPhysicalAddress(Master8259A_LPT1)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_RealtimeTimer],(GetPhysicalAddress(Slave8259A_RealtimeTimer)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_Redirect],(GetPhysicalAddress(Slave8259A_Redirect)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_Reserved1],(GetPhysicalAddress(Slave8259A_Reserved1)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_Reserved2],(GetPhysicalAddress(Slave8259A_Reserved2)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_PS2Mouse],(GetPhysicalAddress(Slave8259A_PS2Mouse)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_FPUException],(GetPhysicalAddress(Slave8259A_FPUException)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_ATA],(GetPhysicalAddress(Slave8259A_ATA)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_Slave8259A_Reserved3],(GetPhysicalAddress(Slave8259A_Reserved3)),GDTSelectorIDT,0x8E);
   MakeGateDescriptor(idt[IDT_System_Call],(GetPhysicalAddress(System_Call)),GDTSelectorIDT,0xEE); 
   MakeIDTPtr((idtptr),((sizeof(GATE)*IDT_AMOUNT)-1),(GetPhysicalAddress(idt)));
  /*--------Use new gdt table---------*/
   __asm__ __volatile__(
       "lgdt  gdtptr\n\t"
       "cli         \n\t"
       "inb   $0x92,%%al\n\t"
       "orb   $0x02,%%al\n\t"
       "outb  %%al,$0x92\n\t"
       "movl  %%cr0,%%eax\n\t"
       "orl   $0x1,%%eax\n\t"
       "movl  %%eax,%%cr0\n\t"
       "ljmpl $0x8,$LABEL_LASTJUMP\n"
       "LABEL_LASTJUMP:\n\t"
       :
       :
       :"eax");
   SetDS(Kernel_DS);
   SetES(Kernel_ES);
   SetSS(Kernel_SS);
   SetGS(Kernel_GS);
 /*----------Use tss------------*/
   SetTR(GDTSelectorTSS);
 /*----------Load the idt-------*/
   __asm__ __volatile__(
       "cli\n\t"
       "lidt idtptr\n\t"
       ::);
 /*----------Enable the 8253/8254 PIT---------*/
   ByteToPort(PIT8253MODECONTROLREGISTER,0x34);
   ByteToPort(PIT8253COUNTER0,(U1B)(PIT8253FREQUENCY/PIT8253HZ));
   ByteToPort(PIT8253COUNTER0,(((U1B)(PIT8253FREQUENCY/PIT8253HZ))>>8));
 /*----------Enable the 8259A-----------------*/
   ByteToPort(MASTER8259ACONTROLPORT,0x11);
   ByteToPort(SLAVE8259ACONTROLPORT ,0X11);
   ByteToPort(MASTER8259ACONTROLMASKPORT,0x20);
   ByteToPort(SLAVE8259ACONTROLMASKPORT ,0x28);
   ByteToPort(MASTER8259ACONTROLMASKPORT,0x04);
   ByteToPort(SLAVE8259ACONTROLMASKPORT ,0x02);
   ByteToPort(MASTER8259ACONTROLMASKPORT,0x01);
   ByteToPort(SLAVE8259ACONTROLMASKPORT ,0x01);
   ByteToPort(MASTER8259ACONTROLMASKPORT,0xFE);
   ByteToPort(SLAVE8259ACONTROLMASKPORT ,0xFF);   
 //  STI();

   return ARTIST_ERROR_OK;
}


